package com.example.rotateimageview.passwordedit

import android.content.Context
import android.graphics.*
import android.text.InputType
import android.util.AttributeSet
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.View.OnKeyListener
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputConnection
import android.view.inputmethod.InputMethodManager
import com.example.rotateimageview.MyApplication
import com.example.rotateimageview.R

/**
 * author  : Liushuai
 * time    : 2021/11/6 8:48
 * desc    :
 */
class PasswordEditText @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
) : View(context, attributeSet, 0) {
    //密码位数
    private var passwordLength = 4
    private var mTextColor = 0
    private var mTextSize = 40f

    //间隔
    private var itemPadding = dip2px(12f)

    //单个数字包括背景宽度
    private var itemWidth = 30

    //单个框颜色
    private var bgItemColor = 0

    //是否密文显示
    private var isCipherEnable = true

    //密文符号
    private var cipherString = "•"

    private var password = arrayOfNulls<String>(passwordLength)

    private val mPaintBg = Paint()
    private val mPaintTv = Paint()

    private val rectTv = Rect()

    //用于添加删除标记
    private var currentInputPosition = 0

    private var operationListener: OperationListener? = null

    private val inputManager by lazy {
        getContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    }

    //监听键盘
    private val mKeyListener = OnKeyListener { v, keyCode, event ->
        val action = event.action
        if (action == KeyEvent.ACTION_DOWN) {
            if (keyCode == KeyEvent.KEYCODE_DEL) {
                //删除
                if (currentInputPosition == 0) {
                    return@OnKeyListener true
                }
                password[currentInputPosition - 1] = null
                currentInputPosition--
                postInvalidate()
                operationListener?.deleteOperationCallBack()
                return@OnKeyListener true
            }

            if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
                //数字键
                if (currentInputPosition == passwordLength) {
                    return@OnKeyListener true
                }
                password[currentInputPosition] = (keyCode - 7).toString()
                currentInputPosition++
                postInvalidate()
                operationListener?.inputOperationCallBack()
                return@OnKeyListener true
            }

            if (keyCode == KeyEvent.KEYCODE_ENTER) {
                operationListener?.completeOperationCallBack()
                return@OnKeyListener true
            }
        }
        return@OnKeyListener false
    }


    init {
        val typedArray = context.obtainStyledAttributes(
            attributeSet,
            R.styleable.CustomPasswordEditText,
            0,
            0
        )
        passwordLength = typedArray.getInt(R.styleable.CustomPasswordEditText_et_number, 4)

        mTextColor = typedArray.getInt(
            R.styleable.CustomPasswordEditText_et_text_color, Color.parseColor(
                "#333333"
            )
        )

        bgItemColor = typedArray.getInt(
            R.styleable.CustomPasswordEditText_et_bg_item_color, Color.parseColor(
                "#F5F5F8"
            )
        )

        isCipherEnable = typedArray.getBoolean(R.styleable.CustomPasswordEditText_et_cipher, true)

        typedArray.recycle()

        mPaintBg.apply {
            isAntiAlias = true
            style = Paint.Style.FILL
            color = bgItemColor
        }

        mPaintTv.apply {
            isAntiAlias = true
            style = Paint.Style.FILL
            color = mTextColor
            textSize = mTextSize
            textAlign = Paint.Align.CENTER
        }

        setOnKeyListener(mKeyListener)
        //这个一定要加 
        isFocusableInTouchMode = true;
    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        var width = 0
        when (MeasureSpec.getMode(widthMeasureSpec)) {
            MeasureSpec.UNSPECIFIED, MeasureSpec.AT_MOST -> {
                width = itemWidth * passwordLength + itemPadding * (passwordLength - 1)
            }

            MeasureSpec.EXACTLY -> {
                width = MeasureSpec.getSize(widthMeasureSpec)
                itemWidth = (width - itemPadding * (passwordLength - 1)) / passwordLength
            }
        }
        setMeasuredDimension(width, itemWidth)
    }

    override fun onDraw(canvas: Canvas) {
        drawBgItems(canvas)
        drawPasswordNumber(canvas)
        super.onDraw(canvas)
    }

    //绘制背景框
    private fun drawBgItems(canvas: Canvas) {
        for (i in password.indices) {
            val rect = RectF(
                paddingLeft + (i * itemWidth + (i) * itemPadding).toFloat(),
                0f,
                paddingLeft + ((i + 1) * itemWidth + i * itemPadding).toFloat(),
                itemWidth.toFloat()
            )
            canvas.drawRoundRect(rect, 5f, 5f, mPaintBg)
        }
    }

    //绘制文字
    private fun drawPasswordNumber(canvas: Canvas) {
        for (i in password.indices) {
            if (password[i] != null) {
                //没有开启明文显示，绘制密码密文
                val txt = if (isCipherEnable) cipherString else password[i]
                mPaintTv.getTextBounds(txt, 0, txt!!.length, rectTv)
                val offset = (rectTv.top + rectTv.bottom) / 2
                canvas.drawText(
                    txt,
                    (paddingLeft + itemWidth * i + itemPadding * i + itemWidth / 2).toFloat(),
                    (paddingTop + itemWidth / 2).toFloat() - offset, mPaintTv
                )
            }
        }
    }


    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event!!.action == MotionEvent.ACTION_DOWN) {
            requestFocus()
            inputManager.showSoftInput(this, InputMethodManager.SHOW_FORCED)
//            inputManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS)
            return true
        }
        return super.onTouchEvent(event)
    }

    override fun onWindowFocusChanged(hasWindowFocus: Boolean) {
        super.onWindowFocusChanged(hasWindowFocus)
        if (!hasWindowFocus) {
            inputManager.hideSoftInputFromWindow(this.windowToken, 0)
        }
    }

    override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? {
        outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
        return super.onCreateInputConnection(outAttrs)
    }

    //获取输入内容
    fun getTextContent(): String {
        val sb = StringBuilder()
        for (p in password) {
            p?.let {
                sb.append(p)
            }
        }
        return sb.toString()
    }

    //操作回调
    interface OperationListener {
        fun inputOperationCallBack()

        fun completeOperationCallBack()

        fun deleteOperationCallBack()
    }

    fun setOperationListener(listener: OperationListener) {
        this.operationListener = listener
    }

    fun dip2px(dpValue: Float): Int {
        val scale = MyApplication.instance.resources.displayMetrics.density
        return (dpValue * scale + 0.5f).toInt()
    }
}